home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / mail_bbs.c < prev    next >
C/C++ Source or Header  |  1992-01-08  |  5KB  |  198 lines

  1. /* @(#) $Header: mail_bbs.c,v 1.9 92/01/08 13:45:23 deyke Exp $ */
  2.  
  3. /* BBS Mail Delivery Agent */
  4.  
  5. #include <sys/types.h>
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <sys/stat.h>
  11. #include <time.h>
  12. #include <unistd.h>
  13.  
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "transport.h"
  17. #include "mail.h"
  18.  
  19. struct mesg {
  20.   int  state;
  21. #define BBS_OPEN_STATE    0
  22. #define BBS_COMMAND_STATE 1
  23. #define BBS_SUBJECT_STATE 2
  24. #define BBS_SEND_STATE    3
  25. #define BBS_UNLK_STATE    4
  26. #define BBS_QUIT_STATE    5
  27.   char  buf[1024];
  28.   int  cnt;
  29.   FILE * fp;
  30.   struct mailsys *sp;
  31.   struct transport_cb *tp;
  32. };
  33.  
  34. static void mail_bbs_transaction __ARGS((struct mesg *mp));
  35. static void mail_bbs_recv_upcall __ARGS((struct transport_cb *tp, int cnt));
  36. static void mail_bbs_send_upcall __ARGS((struct transport_cb *tp, int cnt));
  37. static void mail_bbs_state_upcall __ARGS((struct transport_cb *tp));
  38.  
  39. /*---------------------------------------------------------------------------*/
  40.  
  41. static void mail_bbs_transaction(mp)
  42. struct mesg *mp;
  43. {
  44.  
  45.   char  tmp[1024];
  46.   struct mailjob *jp;
  47.   struct stat statbuf;
  48.   struct tm *tm;
  49.  
  50.   jp = mp->sp->jobs;
  51.   switch (mp->state) {
  52.   case BBS_OPEN_STATE:
  53.     if (mp->buf[mp->cnt-1] == '>') {
  54. nextjob:
  55.       mp->state = BBS_COMMAND_STATE;
  56.       sprintf(tmp,
  57.           "S %s @ %s < %s\n",
  58.           get_user_from_path(jp->to),
  59.           get_host_from_path(jp->to),
  60.           get_user_from_path(jp->from));
  61.       transport_send(mp->tp, qdata(tmp, strlen(tmp)));
  62.     }
  63.     break;
  64.   case BBS_COMMAND_STATE:
  65.     mp->state = BBS_SUBJECT_STATE;
  66.     sprintf(tmp, "%s\n", *jp->subject ? jp->subject : "no subject");
  67.     transport_send(mp->tp, qdata(tmp, strlen(tmp)));
  68.     break;
  69.   case BBS_SUBJECT_STATE:
  70.     if (!stat(jp->cfile, &statbuf) && (mp->fp = fopen(jp->dfile, "r"))) {
  71.       mp->state = BBS_SEND_STATE;
  72.       while (fgets(tmp, sizeof(tmp), mp->fp) && *tmp != '\n') ;
  73.       tm = gmtime(&statbuf.st_mtime);
  74.       sprintf(tmp,
  75.           "R:%02d%02d%02d/%02d%02dz @%-6s [WAMPES BBS Mailer]\n",
  76.           tm->tm_year % 100,
  77.           tm->tm_mon + 1,
  78.           tm->tm_mday,
  79.           tm->tm_hour,
  80.           tm->tm_min,
  81.           Hostname);
  82.       transport_send(mp->tp, qdata(tmp, strlen(tmp)));
  83.     } else {
  84.       mp->state = BBS_QUIT_STATE;
  85.       transport_close(mp->tp);
  86.     }
  87.     break;
  88.   case BBS_SEND_STATE:
  89.     break;
  90.   case BBS_UNLK_STATE:
  91.     if (mp->buf[mp->cnt-1] == '>') {
  92.       unlink(jp->cfile);
  93.       unlink(jp->dfile);
  94.       unlink(jp->xfile);
  95.       mp->sp->jobs = jp->next;
  96.       free(jp);
  97.       if (jp = mp->sp->jobs) goto nextjob;
  98.       mp->state = BBS_QUIT_STATE;
  99.       transport_close(mp->tp);
  100.     }
  101.     break;
  102.   case BBS_QUIT_STATE:
  103.     break;
  104.   }
  105. }
  106.  
  107. /*---------------------------------------------------------------------------*/
  108.  
  109. static void mail_bbs_recv_upcall(tp, cnt)
  110. struct transport_cb *tp;
  111. int  cnt;
  112. {
  113.  
  114.   int  c;
  115.   struct mbuf *bp;
  116.   struct mesg *mp;
  117.  
  118.   mp = (struct mesg *) tp->user;
  119.   mp->sp->state = MS_TALKING;
  120.   transport_recv(tp, &bp, 0);
  121.   while ((c = PULLCHAR(&bp)) != -1)
  122.     if (c == '\n') {
  123.       mp->buf[mp->cnt] = '\0';
  124.       mail_bbs_transaction(mp);
  125.       mp->cnt = 0;
  126.     }
  127.     else if (mp->cnt < sizeof(mp->buf) - 1)
  128.       mp->buf[mp->cnt++] = c;
  129. }
  130.  
  131. /*---------------------------------------------------------------------------*/
  132.  
  133. static void mail_bbs_send_upcall(tp, cnt)
  134. struct transport_cb *tp;
  135. int  cnt;
  136. {
  137.  
  138.   char  *p;
  139.   int  c;
  140.   struct mbuf *bp;
  141.   struct mesg *mp;
  142.  
  143.   mp = (struct mesg *) tp->user;
  144.   if (mp->state != BBS_SEND_STATE || cnt <= 0) return;
  145.   if (!(bp = alloc_mbuf(cnt))) return;
  146.   p = bp->data;
  147.   while (p - bp->data < cnt && (c = getc(mp->fp)) != EOF)
  148.     if (c && c != '\004' && c != '\032') *p++ = c;
  149.   if (bp->cnt = p - bp->data)
  150.     transport_send(tp, bp);
  151.   else
  152.     free_p(bp);
  153.   if (c == EOF) {
  154.     fclose(mp->fp);
  155.     mp->fp = 0;
  156.     transport_send(mp->tp, qdata("\032\n", 2));
  157.     mp->state = BBS_UNLK_STATE;
  158.   }
  159. }
  160.  
  161. /*---------------------------------------------------------------------------*/
  162.  
  163. static void mail_bbs_state_upcall(tp)
  164. struct transport_cb *tp;
  165. {
  166.   struct mesg *mp;
  167.  
  168.   if (mp = (struct mesg *) tp->user) {
  169.     if (mp->fp) fclose(mp->fp);
  170.     if (!mp->sp->jobs)
  171.       mp->sp->state = MS_SUCCESS;
  172.     else
  173.       mailer_failed(mp->sp);
  174.     free(mp);
  175.   }
  176.   transport_del(tp);
  177. }
  178.  
  179. /*---------------------------------------------------------------------------*/
  180.  
  181. void mail_bbs(sp)
  182. struct mailsys *sp;
  183. {
  184.   struct mesg *mp;
  185.  
  186.   mp = calloc(1, sizeof(*mp));
  187.   mp->sp = sp;
  188.   if (mp->tp = transport_open(sp->protocol, sp->address, mail_bbs_recv_upcall, mail_bbs_send_upcall, mail_bbs_state_upcall, (char *) mp)) {
  189.     mp->tp->recv_mode = EOL_LF;
  190.     mp->tp->send_mode = strcmp(sp->protocol, "tcp") ? EOL_CR : EOL_CRLF;
  191.     transport_set_timeout(mp->tp, 3600);
  192.   } else {
  193.     mailer_failed(sp);
  194.     free(mp);
  195.   }
  196. }
  197.  
  198.